#include "database_query_holder.h"

#include "log.h"
#include "database_query_result.h"
#include "database_preparedstatement.h"
#include "database_mysql_connection.h"

namespace afcore {
namespace database {

void CSqlQueryHolderBase::SetSize(size_t size) {
  queries_.resize(size);
}

CSqlQueryHolderBase::~CSqlQueryHolderBase() {
  for (auto& query : queries_) {
    delete query.first;
  }
}

RPreparedQueryResultSptr CSqlQueryHolderBase::GetPreparedResult(size_t index) {
  if (index < queries_.size()) {
    return queries_[index].second;
  } else {
    return RPreparedQueryResultSptr(nullptr);
  }
}

void CSqlQueryHolderBase::SetPreparedResult(size_t index, CPreparedResultSet *result) {
  if (result && !result->GetRowCount()) {
    delete result;
    result = nullptr;
  }

  if (index < queries_.size()) {
    queries_[index].second = RPreparedQueryResultSptr(result);
  }
}

bool CSqlQueryHolderBase::SetPreparedQueryImpl(size_t index, CPreparedStatementBase *stmt) {
  if (queries_.size() <= index) {
    LOG_ERROR("Query index ({}) out of range (size: {}) for prepared statement", static_cast<uint32_t>(index),
      static_cast<uint32_t>(queries_.size()));
    return false;
  }

  queries_[index].first = stmt;
  return true;
}

bool CSqlQueryHolderTask::Execute() {
  executed_ = true;

  if (!holder_) {
    return false;
  }

  for (size_t i = 0; i < holder_->queries_.size(); ++i) {
    if (CPreparedStatementBase* stmt = holder_->queries_[i].first) {
      holder_->SetPreparedResult(i, conn_->Query(stmt));
    }
  }

  result_.set_value(holder_);
  return true;
}

CSqlQueryHolderTask::~CSqlQueryHolderTask() {
  if (!executed_) {
    delete holder_;
  }
}

} // !namespace database
} // !namespace afcore